#include "testTermDocPos.h"
#include "../RTT/TermDocPos.h"
#include "testTools.h"


#include <stdlib.h>  
#include <iostream>

#include <algorithm>    // std::make_heap, std::pop_heap, std::push_heap, std::sort_heap

using namespace std;

void testTDP()
{
	TermDocPos* terminos = new TermDocPos("terminos.bin",true);

	int recuperador1[3],recuperador2[3],recuperador3[3],recuperador4[3],recuperador5[3],recuperador6[3];
	int sol1[3] = {1,5,3};
	int sol2[3] = {33,22,11};
	int sol3[3] = {666,999,666};
	int sol4[3] = {1,5,5};
	int sol5[3] = {3,1,3};
	int sol6[3] = {0,1,1};

	cout << "\ntest arch (idTerm,idDoc,pos): ";
	cout << "\n\nPruebo guardar terminos: ";

	size_t id1 = terminos->agregar(sol1[0],sol1[1],sol1[2]);
	size_t id2 = terminos->agregar(sol2[0],sol2[1],sol2[2]);
	size_t id3 = terminos->agregar(sol3[0],sol3[1],sol3[2]);
	size_t id4 = terminos->agregar(sol4[0],sol4[1],sol4[2]);

	imprimirSelectivo("\nguardo primer termino: \t\t",(id1==0));
	imprimirSelectivo("\nguardo segundo termino:\t\t",(id2==1));
	imprimirSelectivo("\nguardo tercer termino: \t\t",(id3==2));
	imprimirSelectivo("\nguardo cuarto termino: \t\t",(id4==3));

	cout << "\n\nrecupero los terminos agregados: ";

	terminos->devolver(&(recuperador1[0]),&(recuperador1[1]),&(recuperador1[2]),id1);
	terminos->devolver(&(recuperador2[0]),&(recuperador2[1]),&(recuperador2[2]),id2);
	terminos->devolver(&(recuperador3[0]),&(recuperador3[1]),&(recuperador3[2]),id3);
	terminos->devolver(&(recuperador4[0]),&(recuperador4[1]),&(recuperador4[2]),id4);	

	imprimirSelectivo("\nrecupero primer termino: \t",sonIguales(recuperador1,sol1));
	imprimirSelectivo("\nrecupero segundo termino: \t",sonIguales(recuperador2,sol2));
	imprimirSelectivo("\nrecupero tercer termino: \t",sonIguales(recuperador3,sol3));
	imprimirSelectivo("\nrecupero cuarto termino: \t",sonIguales(recuperador4,sol4));

	cout << "\n\nhago 1 swap: id1 <--> id3:";
	terminos->swap(id1,id3);

	terminos->devolver(&(recuperador1[0]),&(recuperador1[1]),&(recuperador1[2]),id1);
	terminos->devolver(&(recuperador2[0]),&(recuperador2[1]),&(recuperador2[2]),id2);
	terminos->devolver(&(recuperador3[0]),&(recuperador3[1]),&(recuperador3[2]),id3);
	terminos->devolver(&(recuperador4[0]),&(recuperador4[1]),&(recuperador4[2]),id4);

	imprimirSelectivo("\nrecupero primer termino: \t",sonIguales(recuperador1,sol3));
	imprimirSelectivo("\nrecupero segundo termino: \t",sonIguales(recuperador2,sol2));
	imprimirSelectivo("\nrecupero tercer termino: \t",sonIguales(recuperador3,sol1));
	imprimirSelectivo("\nrecupero cuarto termino: \t",sonIguales(recuperador4,sol4));

	cout << "\n\nordeno: ";
	terminos->sortExterno();

	terminos->devolver(&(recuperador1[0]),&(recuperador1[1]),&(recuperador1[2]),id1);
	terminos->devolver(&(recuperador2[0]),&(recuperador2[1]),&(recuperador2[2]),id2);
	terminos->devolver(&(recuperador3[0]),&(recuperador3[1]),&(recuperador3[2]),id3);
	terminos->devolver(&(recuperador4[0]),&(recuperador4[1]),&(recuperador4[2]),id4);

	imprimirSelectivo("\nrecupero primer termino: \t",sonIguales(recuperador1,sol1));
	imprimirSelectivo("\nrecupero segundo termino: \t",sonIguales(recuperador2,sol4));
	imprimirSelectivo("\nrecupero tercer termino: \t",sonIguales(recuperador3,sol2));
	imprimirSelectivo("\nrecupero cuarto termino: \t",sonIguales(recuperador4,sol3));


	cout << "\n\nguardo 2+ y vuelvo a ordenar: ";
	size_t id5 = terminos->agregar(sol5[0],sol5[1],sol5[2]);
	size_t id6 = terminos->agregar(sol6[0],sol6[1],sol6[2]);

	cout << "\n\nrecupero: ";
	terminos->sortExterno();

	terminos->devolver(&(recuperador1[0]),&(recuperador1[1]),&(recuperador1[2]),id1);
	terminos->devolver(&(recuperador2[0]),&(recuperador2[1]),&(recuperador2[2]),id2);
	terminos->devolver(&(recuperador3[0]),&(recuperador3[1]),&(recuperador3[2]),id3);
	terminos->devolver(&(recuperador4[0]),&(recuperador4[1]),&(recuperador4[2]),id4);
	terminos->devolver(&(recuperador5[0]),&(recuperador5[1]),&(recuperador5[2]),id5);
	terminos->devolver(&(recuperador6[0]),&(recuperador6[1]),&(recuperador6[2]),id6);

	imprimirSelectivo("\nrecupero primer termino: \t",sonIguales(recuperador1,sol6));
	imprimirSelectivo("\nrecupero segundo termino: \t",sonIguales(recuperador2,sol1));
	imprimirSelectivo("\nrecupero tercer termino: \t",sonIguales(recuperador3,sol4));
	imprimirSelectivo("\nrecupero cuarto termino: \t",sonIguales(recuperador4,sol5));
	imprimirSelectivo("\nrecupero quinto termino: \t",sonIguales(recuperador5,sol2));
	imprimirSelectivo("\nrecupero sexto termino: \t",sonIguales(recuperador6,sol3));


	size_t cant = terminos->obtenerCantidadDeElementos();
	imprimirSelectivo("\nchequeo cantidad de terminos: \t",(cant==6));

	delete(terminos);
}

void testsOrdenamiento(){

	cout << "\n\ntest ordenar (idTerm,idDoc,pos): ";

	testTDPSort();
	testHeapSort();
	testHeapSortInt();
}

void testTDPSort(){
	TermDocPos* terminos = new TermDocPos("terminos.bin",true);
	
	bool result = true;	

	srand(time(NULL));
	for (size_t i=0 ; i<1000 ; i++){
	
		int idTerm = rand()%100;
		int idDoc  = rand()%20;
		int pos    = rand()%100;

		terminos->agregar(idTerm,idDoc,pos);
	}	
	terminos->sortExterno();

	for (size_t i=0 ; i<999 ; i++){

		int recuperador1[3],recuperador2[3];
		terminos->devolver(&(recuperador1[0]),&(recuperador1[1]),&(recuperador1[2]),i);
		terminos->devolver(&(recuperador2[0]),&(recuperador2[1]),&(recuperador2[2]),i+1);

		bool mayorIdTerm = (recuperador1[0] > recuperador2[0]);
		bool igualTerm   = (recuperador1[0] == recuperador2[0]);

		bool mayorIdDoc  = (recuperador1[1] > recuperador2[1]);
		bool igualDoc    = (recuperador1[1] == recuperador2[1]);

		bool mayorPos    = (recuperador1[2] > recuperador2[2]);

		if( mayorIdTerm || (igualTerm && mayorIdDoc) || (igualTerm && igualDoc && mayorPos) )
			result = false;
	}
	imprimirSelectivo("\nordeno 1000 elem y chequeo que esten ordenados: \t",result);

	delete(terminos);	
}

void testHeapSort(){
	vector<Clave3Int> elementosAOrdenar;
	
	bool result = true;

	srand(time(NULL));
	for (size_t i=0 ; i<1000 ; i++){
	
		int idTerm = rand()%100;
		int idDoc  = rand()%20;
		int pos    = rand()%100;

		Clave3Int elemento(idTerm,idDoc,pos);
		elementosAOrdenar.push_back(elemento);
	}	

	std::make_heap (elementosAOrdenar.begin(),elementosAOrdenar.end());
	std::sort_heap (elementosAOrdenar.begin(),elementosAOrdenar.end());

	for (size_t i=0;i<999;i++){

		int recuperador1[3],recuperador2[3];

		recuperador1[0] = (elementosAOrdenar[i]).getClave1();
		recuperador1[1] = (elementosAOrdenar[i]).getClave2();
		recuperador1[2] = (elementosAOrdenar[i]).getClave3();

		recuperador2[0] = (elementosAOrdenar[i+1]).getClave1();
		recuperador2[1] = (elementosAOrdenar[i+1]).getClave2();
		recuperador2[2] = (elementosAOrdenar[i+1]).getClave3();

		bool mayorIdTerm = (recuperador1[0] > recuperador2[0]);
		bool igualTerm   = (recuperador1[0] == recuperador2[0]);

		bool mayorIdDoc  = (recuperador1[1] > recuperador2[1]);
		bool igualDoc    = (recuperador1[1] == recuperador2[1]);

		bool mayorPos    = (recuperador1[2] > recuperador2[2]);

		if( mayorIdTerm || (igualTerm && mayorIdDoc) || (igualTerm && igualDoc && mayorPos) )
			result = false;
	}
	imprimirSelectivo("\nordeno 1000 claves3Int y chequeo que esten ordenados: \t",result);
}

void testHeapSortInt(){
	vector<int> elementosAOrdenar;
	
	bool result = true;

	srand(time(NULL));
	for (size_t i=0 ; i<1000 ; i++){
	
		int dato = rand()%100;
		elementosAOrdenar.push_back(dato);
	}	

	std::make_heap (elementosAOrdenar.begin(),elementosAOrdenar.end());
	std::sort_heap (elementosAOrdenar.begin(),elementosAOrdenar.end());

	for (size_t i=0;i<999;i++){

		int recuperador1 = elementosAOrdenar[i];
		int recuperador2 = elementosAOrdenar[i+1];

		if( recuperador1 > recuperador2 )
			result = false;	
	}
	imprimirSelectivo("\nordeno 1000 enteros y chequeo que esten ordenados: \t",result);
	cout << "\n";
}

